Moved GtkSizeRequest cache to GtkWidget->priv
authorTristan Van Berkom <tristan.van.berkom@gmail.com>
Thu, 9 Sep 2010 06:02:56 +0000 (15:02 +0900)
committerTristan Van Berkom <tristan.van.berkom@gmail.com>
Thu, 9 Sep 2010 08:19:18 +0000 (17:19 +0900)
Now that we have a private data installed directly on
the GtkWidget instance it makes no sense to cache the size
requests on widget qdata. This change will generally make
GTK+ memory less fragmented as well as significantly speed
up the size request process.

gtk/gtkprivate.h
gtk/gtksizerequest.c
gtk/gtkwidget.c
gtk/gtkwidget.h

index e4505420fcd46c35237280d524ab4fbbcd5d7d15..9e5b4cf1411ad3486376c73513f5eb048ad56153 100644 (file)
@@ -114,6 +114,28 @@ gboolean _gtk_fnmatch (const char *pattern,
 #define GTK_DEFAULT_ACCEL_MOD_MASK GDK_META_MASK
 #endif
 
+
+/* With GtkSizeRequest, a widget may be requested
+ * its width for 2 or maximum 3 heights in one resize
+ */
+#define GTK_SIZE_REQUEST_CACHED_SIZES 3
+
+typedef struct
+{
+  guint  age;
+  gint   for_size;
+  gint   minimum_size;
+  gint   natural_size;
+} SizeRequest;
+
+typedef struct {
+  SizeRequest widths[GTK_SIZE_REQUEST_CACHED_SIZES];
+  SizeRequest heights[GTK_SIZE_REQUEST_CACHED_SIZES];
+  guint8      cached_width_age;
+  guint8      cached_height_age;
+} SizeRequestCache;
+
+
 G_END_DECLS
 
 #endif /* __GTK_PRIVATE_H__ */
index 4af24144f55d5e2bd83426d699bd41f0ce708d5f..7c67c7eab902289343726bdf38baadeb216b9754 100644 (file)
 #include "gtkprivate.h"
 #include "gtkintl.h"
 
-/* With GtkSizeRequest, a widget may be requested
- * its width for 2 or maximum 3 heights in one resize
- */
-#define N_CACHED_SIZES 3
-
-typedef struct
-{
-  guint  age;
-  gint   for_size;
-  gint   minimum_size;
-  gint   natural_size;
-} SizeRequest;
-
-typedef struct {
-  SizeRequest widths[N_CACHED_SIZES];
-  SizeRequest heights[N_CACHED_SIZES];
-  guint8      cached_width_age;
-  guint8      cached_height_age;
-} SizeRequestCache;
-
-static GQuark quark_cache = 0;
-
-
 typedef GtkSizeRequestIface GtkSizeRequestInterface;
-G_DEFINE_INTERFACE_WITH_CODE (GtkSizeRequest,
-                              gtk_size_request,
-                              GTK_TYPE_WIDGET,
-                              quark_cache = g_quark_from_static_string ("gtk-size-request-cache"));
+G_DEFINE_INTERFACE (GtkSizeRequest,
+                   gtk_size_request,
+                   GTK_TYPE_WIDGET);
 
 
 static void
@@ -149,7 +125,7 @@ get_cached_size (gint           for_size,
 
   *result = &cached_sizes[0];
 
-  for (i = 0; i < N_CACHED_SIZES; i++)
+  for (i = 0; i < GTK_SIZE_REQUEST_CACHED_SIZES; i++)
     {
       SizeRequest *cs;
 
@@ -169,33 +145,6 @@ get_cached_size (gint           for_size,
   return FALSE;
 }
 
-static void
-destroy_cache (SizeRequestCache *cache)
-{
-  g_slice_free (SizeRequestCache, cache);
-}
-
-static SizeRequestCache *
-get_cache (GtkSizeRequest *widget,
-           gboolean        create)
-{
-  SizeRequestCache *cache;
-
-  cache = g_object_get_qdata (G_OBJECT (widget), quark_cache);
-  if (!cache && create)
-    {
-      cache = g_slice_new0 (SizeRequestCache);
-
-      cache->cached_width_age  = 1;
-      cache->cached_height_age = 1;
-
-      g_object_set_qdata_full (G_OBJECT (widget), quark_cache, cache,
-                               (GDestroyNotify)destroy_cache);
-    }
-
-  return cache;
-}
-
 static void
 do_size_request (GtkWidget      *widget,
                 GtkRequisition *requisition)
@@ -222,7 +171,7 @@ compute_size_for_orientation (GtkSizeRequest    *request,
   g_return_if_fail (minimum_size != NULL || natural_size != NULL);
 
   widget = GTK_WIDGET (request);
-  cache  = get_cache (request, TRUE);
+  cache  = _gtk_widget_peek_request_cache (widget);
 
   if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
     {
@@ -232,7 +181,7 @@ compute_size_for_orientation (GtkSizeRequest    *request,
         found_in_cache = get_cached_size (for_size, cache->widths, &cached_size);
       else
         {
-          memset (cache->widths, 0, N_CACHED_SIZES * sizeof (SizeRequest));
+          memset (cache->widths, 0, GTK_SIZE_REQUEST_CACHED_SIZES * sizeof (SizeRequest));
           cache->cached_width_age = 1;
         }
     }
@@ -244,7 +193,7 @@ compute_size_for_orientation (GtkSizeRequest    *request,
         found_in_cache = get_cached_size (for_size, cache->heights, &cached_size);
       else
         {
-          memset (cache->heights, 0, N_CACHED_SIZES * sizeof (SizeRequest));
+          memset (cache->heights, 0, GTK_SIZE_REQUEST_CACHED_SIZES * sizeof (SizeRequest));
           cache->cached_height_age = 1;
         }
     }
index e21a56902d2e0aa0af0e4e0d51c330ef65e1a787..9a032c5cc441b0dfa3786095181ae6683ae58192 100644 (file)
@@ -168,6 +168,9 @@ struct _GtkWidgetPrivate
    */
   GtkAllocation allocation;
 
+  /* The widget's requested sizes */
+  SizeRequestCache requests;
+
   /* The widget's window or its parent window if it does
    *  not have a window. (Which will be indicated by the
    *  GTK_NO_WINDOW flag being set).
@@ -9071,6 +9074,21 @@ _gtk_widget_peek_colormap (void)
   return NULL;
 }
 
+/**
+ * _gtk_widget_peek_request_cache:
+ * 
+ * Returns the address of the widget's request cache (strictly for
+ * internal use in gtksizerequest.c)
+ * 
+ * Return value: the address of @widget's size request cache.
+ **/
+gpointer
+_gtk_widget_peek_request_cache (GtkWidget *widget)
+{
+  /* Don't bother slowing things down with the return_if_fail guards here */
+  return &widget->priv->requests;
+}
+
 /*
  * _gtk_widget_set_device_window:
  * @widget: a #GtkWidget.
index ad09ba7eea89901c90f6b8c9aa4255881233bc55..b413e0d421328cf932c87460049f56f8c331305a 100644 (file)
@@ -941,6 +941,8 @@ void       _gtk_widget_synthesize_crossing (GtkWidget      *from,
 
 GdkColormap* _gtk_widget_peek_colormap (void);
 
+gpointer     _gtk_widget_peek_request_cache (GtkWidget *widget);
+
 void         _gtk_widget_buildable_finish_accelerator (GtkWidget *widget,
                                                       GtkWidget *toplevel,
                                                       gpointer   user_data);